﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameLib.Utils;
using GameLib.Gameplay.Scripting.Markups;

namespace GameLib.Gameplay.Scripting
{
	public delegate MarkupType ScriptMarkupFactory<MarkupType>() where MarkupType : ScriptMarkup;
	//public delegate ScriptMarkup ScriptMarkupFactory();

	public abstract class ScriptMarkupInfo
	{
		public ScriptMarkupInfo(Name name)
		{
			Name = name;
			//Factory = factory;
		}

		public abstract ScriptMarkup New();

		public Name Name { get; private set; }
		//private ScriptMarkupFactory Factory { get; set; }
	}

	public class ScriptMarkupInfo<MarkupType> : ScriptMarkupInfo where MarkupType : ScriptMarkup
	{
		public ScriptMarkupInfo(Name name, ScriptMarkupFactory<MarkupType> factory)
			: base(name)
		{
			Factory = factory;
		}

		public override ScriptMarkup New()
		{
			return Factory();
		}

		public MarkupType NewSpec()
		{
			return Factory();
		}

		private ScriptMarkupFactory<MarkupType> Factory { get; set; }
	}

	public static class ScriptMarkups
	{
		public static readonly ScriptMarkupInfo<Section> Section = RegisterMarkup<Section>();

		public static ScriptMarkupInfo<MarkupType> RegisterMarkup<MarkupType>() where MarkupType : ScriptMarkup, new()
		{
			MarkupType tempMarkup = new MarkupType();
			Name name = tempMarkup.Name;

			ScriptMarkupInfo<MarkupType> markupInfo = new ScriptMarkupInfo<MarkupType>(name, delegate { return new MarkupType(); });

			if (MarkupInfos.ContainsKey(name))
				throw new Exception(string.Format("Markup named {0} already registered!", name));

			MarkupInfos[markupInfo.Name] = markupInfo;
			return markupInfo;
		}

		public static ScriptMarkupInfo FindMarkupInfo(Name name)
		{
			ScriptMarkupInfo markupInfo;

			if (MarkupInfos.TryGetValue(name, out markupInfo))
				return markupInfo;

			return null;
		}


		private static Dictionary<Name, ScriptMarkupInfo> MarkupInfos = new Dictionary<Name, ScriptMarkupInfo>();


	}
}
